<!--
 * 字典数据新增/编辑表单页面
 * 基于蒜苔系统字典管理设计文档重写，提供完整的表单功能和验证
 -->

<template>
  <a-modal
    v-model:open="visible"
    :title="isEdit ? '编辑字典数据' : '新增字典数据'"
    width="700px"
    :mask-closable="false"
    :confirmLoading="loading"
    @ok="handleSubmit"
    @cancel="handleCancel"
  >
    <a-form
      ref="formRef"
      :model="formData"
      :rules="formRules"
      :label-col="{ span: 6 }"
      :wrapper-col="{ span: 18 }"
    >
      <a-form-item label="字典类型" name="dictType">
        <a-select
          v-model:value="formData.dictType"
          placeholder="请选择字典类型"
          :loading="dictTypeLoading"
          :disabled="isEdit"
          show-search
          :filter-option="filterDictTypeOption"
          @change="handleDictTypeChange"
        >
          <a-select-option
            v-for="dictType in dictTypeOptions"
            :key="dictType.dictType"
            :value="dictType.dictType"
            :label="dictType.dictName"
          >
            <div class="dict-type-option">
              <span class="dict-type-name">{{ dictType.dictName }}</span>
              <a-tag size="small" :color="dictType.status === 1 ? 'success' : 'error'">
                {{ dictType.dictType }}
              </a-tag>
            </div>
          </a-select-option>
        </a-select>
        <div class="form-help-text">
          选择字典数据所属的字典类型，创建后不可修改
        </div>
      </a-form-item>

      <a-form-item label="字典标签" name="dictLabel">
        <a-input
          v-model:value="formData.dictLabel"
          placeholder="请输入字典标签，如：正常"
          :maxlength="100"
          show-count
        />
        <div class="form-help-text">
          字典标签是显示给用户看的文本，如"正常"、"禁用"等
        </div>
      </a-form-item>

      <a-form-item label="字典值" name="dictValue">
        <a-input
          v-model:value="formData.dictValue"
          placeholder="请输入字典值，如：1"
          :maxlength="100"
          show-count
        >
          <template #addonBefore>
            <CodeOutlined />
          </template>
        </a-input>
        <div class="form-help-text">
          字典值是程序中使用的实际值，如"1"、"0"、"active"等
        </div>
      </a-form-item>

      <a-form-item label="字典描述" name="dictDesc">
        <a-textarea
          v-model:value="formData.dictDesc"
          placeholder="请输入字典描述，说明该字典项的具体含义和用途"
          :maxlength="500"
          :rows="3"
          show-count
        />
      </a-form-item>

      <a-form-item label="状态" name="status">
        <a-radio-group v-model:value="formData.status">
          <a-radio :value="1">
            <a-tag color="success">启用</a-tag>
            <span style="margin-left: 8px;">字典数据启用后可以正常使用</span>
          </a-radio>
          <a-radio :value="0">
            <a-tag color="error">禁用</a-tag>
            <span style="margin-left: 8px;">字典数据禁用后将不可使用</span>
          </a-radio>
        </a-radio-group>
      </a-form-item>

      <a-form-item label="默认值" name="isDefault">
        <a-radio-group v-model:value="formData.isDefault">
          <a-radio :value="1">
            <a-tag color="orange">是</a-tag>
            <span style="margin-left: 8px;">设为该字典类型的默认值</span>
          </a-radio>
          <a-radio :value="0">
            <a-tag color="default">否</a-tag>
            <span style="margin-left: 8px;">不设为默认值</span>
          </a-radio>
        </a-radio-group>
        <div class="form-help-text">
          每个字典类型只能有一个默认值，设置后会自动取消其他项的默认状态
        </div>
      </a-form-item>

      <a-form-item label="排序序号" name="sortOrder">
        <a-input-number
          v-model:value="formData.sortOrder"
          placeholder="请输入排序序号"
          :min="0"
          :max="9999"
          style="width: 200px"
        />
        <div class="form-help-text">
          数值越小排序越靠前，相同数值按创建时间排序
        </div>
      </a-form-item>

      <a-form-item label="样式类" name="cssClass">
        <a-select
          v-model:value="formData.cssClass"
          placeholder="请选择样式类"
          allow-clear
        >
          <a-select-option value="default">
            <a-tag color="default">默认</a-tag>
            <span style="margin-left: 8px;">default</span>
          </a-select-option>
          <a-select-option value="primary">
            <a-tag color="blue">主要</a-tag>
            <span style="margin-left: 8px;">primary</span>
          </a-select-option>
          <a-select-option value="success">
            <a-tag color="green">成功</a-tag>
            <span style="margin-left: 8px;">success</span>
          </a-select-option>
          <a-select-option value="warning">
            <a-tag color="orange">警告</a-tag>
            <span style="margin-left: 8px;">warning</span>
          </a-select-option>
          <a-select-option value="danger">
            <a-tag color="red">危险</a-tag>
            <span style="margin-left: 8px;">danger</span>
          </a-select-option>
          <a-select-option value="processing">
            <a-tag color="blue">处理中</a-tag>
            <span style="margin-left: 8px;">processing</span>
          </a-select-option>
          <a-select-option value="pink">
            <a-tag color="magenta">粉色</a-tag>
            <span style="margin-left: 8px;">pink</span>
          </a-select-option>
        </a-select>
        <div class="form-help-text">
          样式类用于控制字典项在界面上的显示颜色和样式
        </div>
      </a-form-item>

      <!-- 预览区域 -->
      <a-form-item label="预览效果">
        <div class="preview-section">
          <div class="preview-item">
            <span class="preview-label">字典类型：</span>
            <a-tag color="blue">{{ selectedDictTypeName || '未选择' }}</a-tag>
          </div>
          <div class="preview-item">
            <span class="preview-label">字典标签：</span>
            <span class="preview-value">{{ formData.dictLabel || '未填写' }}</span>
          </div>
          <div class="preview-item">
            <span class="preview-label">字典值：</span>
            <a-tag color="purple">{{ formData.dictValue || '未填写' }}</a-tag>
          </div>
          <div class="preview-item">
            <span class="preview-label">状态：</span>
            <a-tag :color="formData.status === 1 ? 'success' : 'error'">
              {{ formData.status === 1 ? '启用' : '禁用' }}
            </a-tag>
          </div>
          <div class="preview-item">
            <span class="preview-label">默认值：</span>
            <a-tag :color="formData.isDefault === 1 ? 'orange' : 'default'">
              {{ formData.isDefault === 1 ? '是' : '否' }}
            </a-tag>
          </div>
          <div class="preview-item">
            <span class="preview-label">样式预览：</span>
            <a-tag :color="getTagColor(formData.cssClass)">
              {{ formData.dictLabel || '样式预览' }}
            </a-tag>
          </div>
          <div class="preview-item">
            <span class="preview-label">排序：</span>
            <span class="preview-value">{{ formData.sortOrder }}</span>
          </div>
        </div>
      </a-form-item>
    </a-form>
  </a-modal>
</template>

<script lang="ts" setup>
import { ref, reactive, computed, nextTick, onMounted } from 'vue';
import { message } from 'ant-design-vue';
import { CodeOutlined } from '@ant-design/icons-vue';
import type { FormInstance, Rule } from 'ant-design-vue/es/form';
import type { SysDictData } from './types';
import type { SysDictType } from '../sysdicttype/types';
import { apiSysDictDataAdd, apiSysDictDataEdit, apiSysDictDataFetchDetail } from './api';
import { apiSysDictTypeFetchList } from '../sysdicttype/api';
import { getMockSysDictDataData } from './mock';

// 组件属性
interface Props {
  callbackFunc?: () => void;
  defaultDictType?: string; // 支持从列表页面传入默认字典类型
}

const props = withDefaults(defineProps<Props>(), {
  callbackFunc: () => {},
  defaultDictType: ''
});

// 响应式数据
const visible = ref(false);
const loading = ref(false);
const isEdit = ref(false);
const formRef = ref<FormInstance>();
const dictTypeLoading = ref(false);
const dictTypeOptions = ref<SysDictType[]>([]);

// 表单数据
const formData = reactive<Partial<SysDictData>>({
  dictType: '',
  dictTypeId: 0,
  dictLabel: '',
  dictValue: '',
  dictDesc: '',
  status: 1,
  isDefault: 0,
  sortOrder: 0,
  cssClass: 'default',
  listClass: 'default'
});

// 计算属性：选中的字典类型名称
const selectedDictTypeName = computed(() => {
  const selectedType = dictTypeOptions.value.find(item => item.dictType === formData.dictType);
  return selectedType ? selectedType.dictName : '';
});

// 表单验证规则
const formRules = computed<Record<string, Rule[]>>(() => ({
  dictType: [
    { required: true, message: '请选择字典类型', trigger: 'change' }
  ],
  dictLabel: [
    { required: true, message: '字典标签不能为空', trigger: 'blur' },
    { max: 100, message: '字典标签长度不能超过100个字符', trigger: 'blur' }
  ],
  dictValue: [
    { required: true, message: '字典值不能为空', trigger: 'blur' },
    { max: 100, message: '字典值长度不能超过100个字符', trigger: 'blur' },
    { validator: validateDictValueUnique, trigger: 'blur' }
  ],
  dictDesc: [
    { max: 500, message: '字典描述长度不能超过500个字符', trigger: 'blur' }
  ],
  status: [
    { required: true, message: '请选择状态', trigger: 'change' }
  ],
  isDefault: [
    { required: true, message: '请选择是否为默认值', trigger: 'change' }
  ],
  sortOrder: [
    { type: 'number', min: 0, max: 9999, message: '排序序号必须在0-9999之间', trigger: 'blur' }
  ]
}));

// 验证字典值唯一性
async function validateDictValueUnique(rule: Rule, value: string) {
  if (!value || !formData.dictType) {
    return Promise.resolve();
  }
  
  try {
    // 获取同类型下的所有字典数据检查唯一性
    const mockDataResult = getMockSysDictDataData({ 
      dictType: formData.dictType,
      pageSize: 1000 
    });
    
    const exists = mockDataResult.data.records.some(item => 
      item.dictValue === value && (!isEdit.value || item.id !== formData.id)
    );
    
    if (exists) {
      return Promise.reject('该字典类型下字典值已存在');
    }
    
    return Promise.resolve();
  } catch (error) {
    console.error('验证字典值唯一性失败:', error);
    return Promise.resolve(); // 验证失败时不阻止提交
  }
}

// 获取字典类型选项
async function fetchDictTypeOptions() {
  try {
    dictTypeLoading.value = true;
    const response = await apiSysDictTypeFetchList({ 
      pageSize: 1000, // 获取所有字典类型
      status: 1 // 只获取启用的字典类型
    });
    
    if (response.success && response.data?.records) {
      dictTypeOptions.value = response.data.records;
    } else {
      message.error('获取字典类型列表失败');
    }
  } catch (error) {
    console.error('获取字典类型列表失败:', error);
    message.error('获取字典类型列表失败');
  } finally {
    dictTypeLoading.value = false;
  }
}

// 字典类型选项过滤
function filterDictTypeOption(input: string, option: any) {
  const dictType = option.value.toLowerCase();
  const dictName = option.label.toLowerCase();
  const searchText = input.toLowerCase();
  return dictType.includes(searchText) || dictName.includes(searchText);
}

// 处理字典类型变化
function handleDictTypeChange(value: string) {
  const selectedType = dictTypeOptions.value.find(item => item.dictType === value);
  if (selectedType) {
    formData.dictTypeId = selectedType.id;
    // 同步设置listClass与cssClass
    formData.listClass = formData.cssClass;
  }
}

// 获取标签颜色
function getTagColor(cssClass?: string) {
  const colorMap: Record<string, string> = {
    default: 'default',
    primary: 'blue',
    success: 'green',
    warning: 'orange',
    danger: 'red',
    processing: 'blue',
    pink: 'magenta'
  };
  return colorMap[cssClass || 'default'] || 'default';
}

// 重置表单
function resetForm() {
  Object.assign(formData, {
    dictType: props.defaultDictType || '',
    dictTypeId: 0,
    dictLabel: '',
    dictValue: '',
    dictDesc: '',
    status: 1,
    isDefault: 0,
    sortOrder: 0,
    cssClass: 'default',
    listClass: 'default'
  });
  
  // 如果有默认字典类型，设置对应的dictTypeId
  if (props.defaultDictType) {
    const selectedType = dictTypeOptions.value.find(item => item.dictType === props.defaultDictType);
    if (selectedType) {
      formData.dictTypeId = selectedType.id;
    }
  }
  
  nextTick(() => {
    formRef.value?.clearValidate();
  });
}

// 显示新增表单
function showAdd(dictType?: string) {
  isEdit.value = false;
  resetForm();
  
  // 如果传入了字典类型，设置默认值
  if (dictType) {
    formData.dictType = dictType;
    handleDictTypeChange(dictType);
  }
  
  visible.value = true;
}

// 显示编辑表单
async function showEdit(id: number) {
  console.log('showEdit called with id:', id, 'type:', typeof id);
  isEdit.value = true;
  visible.value = true;
  loading.value = true;
  
  try {
    const response = await apiSysDictDataFetchDetail(id);
    console.log('API response:', response);
    
    if (response.success && response.data) {
      console.log('Setting form data:', response.data);
      Object.assign(formData, response.data);
      // 确保listClass与cssClass同步
      if (!formData.listClass) {
        formData.listClass = formData.cssClass;
      }
    } else {
      console.error('API returned error:', response);
      message.error(response.message || '获取字典数据详情失败');
      visible.value = false;
    }
  } catch (error) {
    console.error('获取字典数据详情失败:', error);
    message.error('获取字典数据详情失败');
    visible.value = false;
  } finally {
    loading.value = false;
  }
}

// 处理表单提交
async function handleSubmit() {
  try {
    await formRef.value?.validate();
    loading.value = true;
    
    const submitData = { 
      ...formData,
      listClass: formData.cssClass // 确保listClass与cssClass同步
    };
    
    if (isEdit.value) {
      // 编辑模式
      const response = await apiSysDictDataEdit(submitData as SysDictData);
      if (response.success) {
        message.success('编辑字典数据成功');
        visible.value = false;
        props.callbackFunc();
      } else {
        message.error(response.message || '编辑字典数据失败');
      }
    } else {
      // 新增模式
      const response = await apiSysDictDataAdd(submitData as SysDictData);
      if (response.success) {
        message.success('新增字典数据成功');
        visible.value = false;
        props.callbackFunc();
      } else {
        message.error(response.message || '新增字典数据失败');
      }
    }
  } catch (error) {
    console.error('表单提交失败:', error);
    if (error && typeof error === 'object' && 'errorFields' in error) {
      // 表单验证失败
      const firstError = (error as any).errorFields?.[0];
      if (firstError?.errors?.[0]) {
        message.error(firstError.errors[0]);
      }
    } else {
      message.error('操作失败，请重试');
    }
  } finally {
    loading.value = false;
  }
}

// 处理取消
function handleCancel() {
  visible.value = false;
  resetForm();
}

// 组件挂载时获取字典类型选项
onMounted(() => {
  fetchDictTypeOptions();
});

// 暴露方法给父组件
defineExpose({
  showAdd,
  showEdit
});
</script>

<style scoped>
/* 表单帮助文本样式 */
.form-help-text {
  color: #999;
  font-size: 12px;
  margin-top: 4px;
  line-height: 1.4;
}

/* 字典类型选项样式 */
.dict-type-option {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
}

.dict-type-name {
  flex: 1;
  margin-right: 8px;
}

/* 预览区域样式 */
.preview-section {
  background: #fafafa;
  border: 1px solid #e8e8e8;
  border-radius: 6px;
  padding: 16px;
}

.preview-item {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
}

.preview-item:last-child {
  margin-bottom: 0;
}

.preview-label {
  color: #666;
  font-size: 14px;
  min-width: 80px;
  margin-right: 8px;
}

.preview-value {
  color: #333;
  font-size: 14px;
}

/* 表单项样式优化 */
:deep(.ant-form-item-label) {
  font-weight: 500;
}

:deep(.ant-input-number) {
  width: 100%;
}

:deep(.ant-radio-group) {
  width: 100%;
}

:deep(.ant-radio) {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
  padding: 8px 12px;
  border: 1px solid #e8e8e8;
  border-radius: 6px;
  transition: all 0.3s;
}

:deep(.ant-radio:hover) {
  border-color: #1890ff;
  background-color: #f0f8ff;
}

:deep(.ant-radio-checked) {
  border-color: #1890ff;
  background-color: #f0f8ff;
}

/* 选择器样式 */
:deep(.ant-select-selector) {
  border-radius: 6px;
}

:deep(.ant-select-selection-item) {
  display: flex;
  align-items: center;
}

/* 状态标签样式 */
:deep(.ant-tag) {
  margin-right: 0;
  border-radius: 4px;
}

/* 输入框前缀图标样式 */
:deep(.ant-input-group-addon) {
  background-color: #fafafa;
  border-color: #d9d9d9;
  border-radius: 6px 0 0 6px;
}

:deep(.ant-input-affix-wrapper) {
  border-radius: 0 6px 6px 0;
}

/* 字符计数样式 */
:deep(.ant-input-show-count-suffix) {
  color: #999;
}

:deep(.ant-textarea-show-count::after) {
  color: #999;
}

/* 表单验证错误样式 */
:deep(.ant-form-item-has-error .ant-input) {
  border-color: #ff4d4f;
}

:deep(.ant-form-item-has-error .ant-input:focus) {
  border-color: #ff4d4f;
  box-shadow: 0 0 0 2px rgba(255, 77, 79, 0.2);
}

:deep(.ant-form-item-has-error .ant-select-selector) {
  border-color: #ff4d4f;
}

:deep(.ant-form-item-has-error .ant-select-focused .ant-select-selector) {
  border-color: #ff4d4f;
  box-shadow: 0 0 0 2px rgba(255, 77, 79, 0.2);
}

/* 模态框样式优化 */
:deep(.ant-modal-header) {
  border-bottom: 1px solid #e8e8e8;
  padding: 16px 24px;
}

:deep(.ant-modal-title) {
  font-size: 16px;
  font-weight: 600;
  color: #333;
}

:deep(.ant-modal-body) {
  padding: 24px;
  max-height: 70vh;
  overflow-y: auto;
}

:deep(.ant-modal-footer) {
  border-top: 1px solid #e8e8e8;
  padding: 12px 24px;
}

/* 加载状态样式 */
:deep(.ant-select-loading) {
  color: #1890ff;
}

/* 选项禁用样式 */
:deep(.ant-select-item-option-disabled) {
  color: #bfbfbf;
}

/* 响应式设计 */
@media (max-width: 768px) {
  :deep(.ant-modal) {
    width: 95% !important;
    margin: 10px auto;
  }
  
  :deep(.ant-form-item-label) {
    text-align: left;
  }
  
  .preview-item {
    flex-direction: column;
    align-items: flex-start;
  }
  
  .preview-label {
    margin-bottom: 4px;
    margin-right: 0;
  }
  
  .dict-type-option {
    flex-direction: column;
    align-items: flex-start;
  }
  
  .dict-type-name {
    margin-bottom: 4px;
    margin-right: 0;
  }
}

/* 滚动条样式 */
:deep(.ant-modal-body::-webkit-scrollbar) {
  width: 6px;
}

:deep(.ant-modal-body::-webkit-scrollbar-track) {
  background: #f1f1f1;
  border-radius: 3px;
}

:deep(.ant-modal-body::-webkit-scrollbar-thumb) {
  background: #c1c1c1;
  border-radius: 3px;
}

:deep(.ant-modal-body::-webkit-scrollbar-thumb:hover) {
  background: #a8a8a8;
}

/* 表单项间距优化 */
:deep(.ant-form-item) {
  margin-bottom: 20px;
}

:deep(.ant-form-item:last-child) {
  margin-bottom: 0;
}

/* 输入框聚焦样式 */
:deep(.ant-input:focus) {
  border-color: #1890ff;
  box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}

:deep(.ant-select-focused .ant-select-selector) {
  border-color: #1890ff;
  box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}

/* 数字输入框样式 */
:deep(.ant-input-number) {
  border-radius: 6px;
}

:deep(.ant-input-number:focus) {
  border-color: #1890ff;
  box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}

/* 文本域样式 */
:deep(.ant-input) {
  border-radius: 6px;
}

:deep(.ant-input:hover) {
  border-color: #40a9ff;
}
</style>